/*!
 * \file test_math_utils_comprehensive.cpp
 * \project WonderTrader
 *
 * \author AI Assistant
 * \date 2024/12/01
 * 
 * \brief 数学工具类的综合测试文件
 * 
 * \details 本文件包含对数学计算工具类的全面测试，涵盖：
 *          - 基础数学运算和统计函数
 *          - 金融数学计算（收益率、波动率等）
 *          - 技术指标计算（移动平均、RSI等）
 *          - 数值精度和边界条件测试
 *          - 性能测试和并发安全测试
 */

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <vector>
#include <cmath>
#include <numeric>
#include <algorithm>
#include <chrono>
#include <thread>
#include <atomic>

// 模拟数学工具类
namespace {

/*!
 * \brief 数学工具类
 * \details 提供常用的数学计算功能
 */
class MathUtils {
public:
    /*!
     * \brief 计算平均值
     * \param values 数值数组
     * \return 平均值
     */
    static double mean(const std::vector<double>& values) {
        if (values.empty()) return 0.0;
        return std::accumulate(values.begin(), values.end(), 0.0) / values.size();
    }
    
    /*!
     * \brief 计算标准差
     * \param values 数值数组
     * \return 标准差
     */
    static double standardDeviation(const std::vector<double>& values) {
        if (values.size() <= 1) return 0.0;
        
        double avg = mean(values);
        double sum_sq_diff = 0.0;
        
        for (double value : values) {
            double diff = value - avg;
            sum_sq_diff += diff * diff;
        }
        
        return std::sqrt(sum_sq_diff / (values.size() - 1));
    }
    
    /*!
     * \brief 计算简单移动平均
     * \param values 数值数组
     * \param period 周期
     * \return 移动平均数组
     */
    static std::vector<double> simpleMovingAverage(const std::vector<double>& values, int period) {
        std::vector<double> result;
        if (values.size() < static_cast<size_t>(period)) return result;
        
        for (size_t i = period - 1; i < values.size(); ++i) {
            double sum = 0.0;
            for (int j = 0; j < period; ++j) {
                sum += values[i - j];
            }
            result.push_back(sum / period);
        }
        
        return result;
    }
    
    /*!
     * \brief 计算指数移动平均
     * \param values 数值数组
     * \param alpha 平滑系数
     * \return 指数移动平均数组
     */
    static std::vector<double> exponentialMovingAverage(const std::vector<double>& values, double alpha) {
        std::vector<double> result;
        if (values.empty()) return result;
        
        result.push_back(values[0]);
        
        for (size_t i = 1; i < values.size(); ++i) {
            double ema = alpha * values[i] + (1 - alpha) * result.back();
            result.push_back(ema);
        }
        
        return result;
    }
    
    /*!
     * \brief 计算收益率
     * \param current_price 当前价格
     * \param previous_price 前一价格
     * \return 收益率
     */
    static double returnRate(double current_price, double previous_price) {
        if (previous_price == 0.0) return 0.0;
        return (current_price - previous_price) / previous_price;
    }
    
    /*!
     * \brief 计算年化波动率
     * \param returns 收益率数组
     * \param trading_days 年交易日数
     * \return 年化波动率
     */
    static double annualizedVolatility(const std::vector<double>& returns, int trading_days = 252) {
        if (returns.empty()) return 0.0;
        double daily_vol = standardDeviation(returns);
        return daily_vol * std::sqrt(trading_days);
    }
    
    /*!
     * \brief 计算最大回撤
     * \param prices 价格数组
     * \return 最大回撤比例
     */
    static double maxDrawdown(const std::vector<double>& prices) {
        if (prices.empty()) return 0.0;
        
        double max_price = prices[0];
        double max_dd = 0.0;
        
        for (double price : prices) {
            if (price > max_price) {
                max_price = price;
            } else {
                double drawdown = (max_price - price) / max_price;
                max_dd = std::max(max_dd, drawdown);
            }
        }
        
        return max_dd;
    }
    
    /*!
     * \brief 计算相关系数
     * \param x 第一个数据序列
     * \param y 第二个数据序列
     * \return 相关系数
     */
    static double correlation(const std::vector<double>& x, const std::vector<double>& y) {
        if (x.size() != y.size() || x.empty()) return 0.0;
        
        double mean_x = mean(x);
        double mean_y = mean(y);
        
        double numerator = 0.0;
        double sum_sq_x = 0.0;
        double sum_sq_y = 0.0;
        
        for (size_t i = 0; i < x.size(); ++i) {
            double diff_x = x[i] - mean_x;
            double diff_y = y[i] - mean_y;
            
            numerator += diff_x * diff_y;
            sum_sq_x += diff_x * diff_x;
            sum_sq_y += diff_y * diff_y;
        }
        
        double denominator = std::sqrt(sum_sq_x * sum_sq_y);
        return (denominator == 0.0) ? 0.0 : numerator / denominator;
    }
    
    /*!
     * \brief 计算RSI指标
     * \param prices 价格数组
     * \param period 计算周期
     * \return RSI值数组
     */
    static std::vector<double> rsi(const std::vector<double>& prices, int period = 14) {
        std::vector<double> result;
        if (prices.size() <= static_cast<size_t>(period)) return result;
        
        // 计算价格变化
        std::vector<double> gains, losses;
        for (size_t i = 1; i < prices.size(); ++i) {
            double change = prices[i] - prices[i-1];
            gains.push_back(change > 0 ? change : 0);
            losses.push_back(change < 0 ? -change : 0);
        }
        
        // 计算初始平均增益和损失
        double avg_gain = 0.0, avg_loss = 0.0;
        for (int i = 0; i < period; ++i) {
            avg_gain += gains[i];
            avg_loss += losses[i];
        }
        avg_gain /= period;
        avg_loss /= period;
        
        // 计算RSI
        for (size_t i = period; i < gains.size(); ++i) {
            avg_gain = (avg_gain * (period - 1) + gains[i]) / period;
            avg_loss = (avg_loss * (period - 1) + losses[i]) / period;
            
            double rs = (avg_loss == 0.0) ? 100.0 : avg_gain / avg_loss;
            double rsi_value = 100.0 - (100.0 / (1.0 + rs));
            result.push_back(rsi_value);
        }
        
        return result;
    }
    
    /*!
     * \brief 检查数值是否接近（用于浮点数比较）
     * \param a 第一个数值
     * \param b 第二个数值
     * \param epsilon 误差范围
     * \return 是否接近
     */
    static bool isClose(double a, double b, double epsilon = 1e-9) {
        return std::abs(a - b) < epsilon;
    }
};

} // anonymous namespace

/*!
 * \brief 数学工具类测试套件
 */
class MathUtilsTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 准备测试数据
        test_prices = {100.0, 102.0, 101.0, 103.0, 105.0, 104.0, 106.0, 108.0, 107.0, 109.0};
        test_returns = {0.02, -0.0098, 0.0198, 0.0194, -0.0095, 0.0192, 0.0189, -0.0093, 0.0187};
    }
    
    void TearDown() override {
        // 测试后清理
    }
    
    std::vector<double> test_prices;
    std::vector<double> test_returns;
};

/*!
 * \brief 测试基础统计函数
 */
TEST_F(MathUtilsTest, TestBasicStatistics) {
    // 测试平均值计算
    std::vector<double> values = {1.0, 2.0, 3.0, 4.0, 5.0};
    double avg = MathUtils::mean(values);
    EXPECT_DOUBLE_EQ(avg, 3.0);
    
    // 测试空数组
    std::vector<double> empty_values;
    EXPECT_DOUBLE_EQ(MathUtils::mean(empty_values), 0.0);
    
    // 测试标准差计算
    double std_dev = MathUtils::standardDeviation(values);
    EXPECT_TRUE(MathUtils::isClose(std_dev, 1.5811, 1e-4));
    
    // 测试单个值的标准差
    std::vector<double> single_value = {5.0};
    EXPECT_DOUBLE_EQ(MathUtils::standardDeviation(single_value), 0.0);
    
    std::cout << "基础统计函数测试通过" << std::endl;
}

/*!
 * \brief 测试移动平均计算
 */
TEST_F(MathUtilsTest, TestMovingAverages) {
    // 测试简单移动平均
    auto sma = MathUtils::simpleMovingAverage(test_prices, 3);
    EXPECT_EQ(sma.size(), test_prices.size() - 2);
    
    // 验证第一个SMA值
    double expected_first_sma = (test_prices[0] + test_prices[1] + test_prices[2]) / 3.0;
    EXPECT_DOUBLE_EQ(sma[0], expected_first_sma);
    
    // 测试指数移动平均
    auto ema = MathUtils::exponentialMovingAverage(test_prices, 0.2);
    EXPECT_EQ(ema.size(), test_prices.size());
    EXPECT_DOUBLE_EQ(ema[0], test_prices[0]);
    
    // 测试周期大于数据长度的情况
    auto empty_sma = MathUtils::simpleMovingAverage(test_prices, 20);
    EXPECT_TRUE(empty_sma.empty());
    
    std::cout << "移动平均计算测试通过" << std::endl;
}

/*!
 * \brief 测试金融指标计算
 */
TEST_F(MathUtilsTest, TestFinancialIndicators) {
    // 测试收益率计算
    double return_rate = MathUtils::returnRate(102.0, 100.0);
    EXPECT_DOUBLE_EQ(return_rate, 0.02);
    
    // 测试零价格情况
    double zero_return = MathUtils::returnRate(100.0, 0.0);
    EXPECT_DOUBLE_EQ(zero_return, 0.0);
    
    // 测试年化波动率
    double vol = MathUtils::annualizedVolatility(test_returns);
    EXPECT_GT(vol, 0.0);
    
    // 测试最大回撤
    std::vector<double> declining_prices = {100.0, 95.0, 90.0, 85.0, 80.0};
    double max_dd = MathUtils::maxDrawdown(declining_prices);
    EXPECT_DOUBLE_EQ(max_dd, 0.2);  // 20%回撤
    
    // 测试无回撤情况
    std::vector<double> rising_prices = {100.0, 105.0, 110.0, 115.0, 120.0};
    double no_dd = MathUtils::maxDrawdown(rising_prices);
    EXPECT_DOUBLE_EQ(no_dd, 0.0);
    
    std::cout << "金融指标计算测试通过" << std::endl;
}

/*!
 * \brief 测试相关性分析
 */
TEST_F(MathUtilsTest, TestCorrelationAnalysis) {
    // 测试完全正相关
    std::vector<double> x = {1.0, 2.0, 3.0, 4.0, 5.0};
    std::vector<double> y = {2.0, 4.0, 6.0, 8.0, 10.0};
    double corr = MathUtils::correlation(x, y);
    EXPECT_TRUE(MathUtils::isClose(corr, 1.0, 1e-10));
    
    // 测试完全负相关
    std::vector<double> neg_y = {10.0, 8.0, 6.0, 4.0, 2.0};
    double neg_corr = MathUtils::correlation(x, neg_y);
    EXPECT_TRUE(MathUtils::isClose(neg_corr, -1.0, 1e-10));
    
    // 测试无相关
    std::vector<double> random_y = {1.0, 5.0, 2.0, 4.0, 3.0};
    double no_corr = MathUtils::correlation(x, random_y);
    EXPECT_TRUE(std::abs(no_corr) < 1.0);
    
    // 测试不同长度数组
    std::vector<double> short_y = {1.0, 2.0};
    double invalid_corr = MathUtils::correlation(x, short_y);
    EXPECT_DOUBLE_EQ(invalid_corr, 0.0);
    
    std::cout << "相关性分析测试通过" << std::endl;
}

/*!
 * \brief 测试技术指标计算
 */
TEST_F(MathUtilsTest, TestTechnicalIndicators) {
    // 测试RSI计算
    std::vector<double> rsi_prices = {44.0, 44.25, 44.5, 43.75, 44.5, 44.0, 44.25, 
                                      44.75, 45.0, 45.25, 45.5, 45.75, 46.0, 46.25, 
                                      46.5, 46.75, 46.5, 46.25, 47.0, 47.25};
    
    auto rsi_values = MathUtils::rsi(rsi_prices, 14);
    EXPECT_GT(rsi_values.size(), 0);
    
    // RSI值应该在0-100之间
    for (double rsi_val : rsi_values) {
        EXPECT_GE(rsi_val, 0.0);
        EXPECT_LE(rsi_val, 100.0);
    }
    
    // 测试数据不足的情况
    std::vector<double> short_prices = {100.0, 101.0, 102.0};
    auto empty_rsi = MathUtils::rsi(short_prices, 14);
    EXPECT_TRUE(empty_rsi.empty());
    
    std::cout << "技术指标计算测试通过" << std::endl;
}

/*!
 * \brief 测试数值精度处理
 */
TEST_F(MathUtilsTest, TestNumericalPrecision) {
    // 测试浮点数比较
    double a = 0.1 + 0.2;
    double b = 0.3;
    EXPECT_FALSE(a == b);  // 直接比较会失败
    EXPECT_TRUE(MathUtils::isClose(a, b, 1e-15));  // 使用精度比较
    
    // 测试极小数值
    double tiny_a = 1e-15;
    double tiny_b = 2e-15;
    EXPECT_TRUE(MathUtils::isClose(tiny_a, tiny_b, 1e-14));
    EXPECT_FALSE(MathUtils::isClose(tiny_a, tiny_b, 1e-16));
    
    // 测试极大数值
    double large_a = 1e15;
    double large_b = 1e15 + 1;
    EXPECT_TRUE(MathUtils::isClose(large_a, large_b, 10.0));
    
    std::cout << "数值精度处理测试通过" << std::endl;
}

/*!
 * \brief 测试边界条件
 */
TEST_F(MathUtilsTest, TestBoundaryConditions) {
    // 测试极值情况
    std::vector<double> extreme_values = {-1e10, 0.0, 1e10};
    double extreme_mean = MathUtils::mean(extreme_values);
    EXPECT_TRUE(MathUtils::isClose(extreme_mean, 0.0, 1e-6));
    
    // 测试NaN和无穷大
    std::vector<double> special_values = {1.0, 2.0, 3.0};
    // 正常情况下不应该产生NaN
    double normal_mean = MathUtils::mean(special_values);
    EXPECT_FALSE(std::isnan(normal_mean));
    EXPECT_FALSE(std::isinf(normal_mean));
    
    // 测试单调序列
    std::vector<double> monotonic = {1.0, 2.0, 3.0, 4.0, 5.0};
    double mono_std = MathUtils::standardDeviation(monotonic);
    EXPECT_GT(mono_std, 0.0);
    
    std::cout << "边界条件测试通过" << std::endl;
}

/*!
 * \brief 测试性能特性
 */
TEST_F(MathUtilsTest, TestPerformanceCharacteristics) {
    // 生成大量测试数据
    const int data_size = 10000;
    std::vector<double> large_dataset;
    large_dataset.reserve(data_size);
    
    for (int i = 0; i < data_size; ++i) {
        large_dataset.push_back(100.0 + std::sin(i * 0.01) * 10.0);
    }
    
    auto start_time = std::chrono::high_resolution_clock::now();
    
    // 执行各种计算
    double avg = MathUtils::mean(large_dataset);
    double std_dev = MathUtils::standardDeviation(large_dataset);
    auto sma = MathUtils::simpleMovingAverage(large_dataset, 20);
    auto ema = MathUtils::exponentialMovingAverage(large_dataset, 0.1);
    double max_dd = MathUtils::maxDrawdown(large_dataset);
    
    auto end_time = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
    
    // 验证结果合理性
    EXPECT_GT(avg, 90.0);
    EXPECT_LT(avg, 110.0);
    EXPECT_GT(std_dev, 0.0);
    EXPECT_EQ(sma.size(), large_dataset.size() - 19);
    EXPECT_EQ(ema.size(), large_dataset.size());
    EXPECT_GE(max_dd, 0.0);
    
    std::cout << "性能测试: " << data_size << " 个数据点计算耗时 " << duration.count() << "ms" << std::endl;
    EXPECT_LT(duration.count(), 1000);  // 应该在1秒内完成
}

/*!
 * \brief 测试多线程安全性
 */
TEST_F(MathUtilsTest, TestThreadSafety) {
    const int num_threads = 4;
    const int operations_per_thread = 100;
    std::atomic<int> success_count{0};
    
    std::vector<std::thread> threads;
    
    for (int t = 0; t < num_threads; ++t) {
        threads.emplace_back([&, t]() {
            for (int i = 0; i < operations_per_thread; ++i) {
                // 生成线程特定的测试数据
                std::vector<double> thread_data;
                for (int j = 0; j < 100; ++j) {
                    thread_data.push_back(t * 100 + i + j * 0.1);
                }
                
                // 执行各种数学计算
                double avg = MathUtils::mean(thread_data);
                double std_dev = MathUtils::standardDeviation(thread_data);
                auto sma = MathUtils::simpleMovingAverage(thread_data, 5);
                
                // 验证结果合理性
                if (avg > 0 && std_dev >= 0 && sma.size() == thread_data.size() - 4) {
                    success_count++;
                }
            }
        });
    }
    
    for (auto& thread : threads) {
        thread.join();
    }
    
    EXPECT_EQ(success_count.load(), num_threads * operations_per_thread);
    std::cout << "多线程安全性测试通过，成功操作: " << success_count.load() << " 次" << std::endl;
}

/*!
 * \brief 测试完整的量化分析工作流程
 */
TEST_F(MathUtilsTest, TestQuantitativeAnalysisWorkflow) {
    // 模拟股票价格数据
    std::vector<double> stock_prices = {
        100.0, 102.5, 101.8, 103.2, 105.1, 104.3, 106.7, 108.2, 107.5, 109.8,
        111.2, 110.5, 112.3, 114.1, 113.4, 115.6, 117.2, 116.8, 118.5, 120.1
    };
    
    // 第一步：计算收益率
    std::vector<double> returns;
    for (size_t i = 1; i < stock_prices.size(); ++i) {
        double ret = MathUtils::returnRate(stock_prices[i], stock_prices[i-1]);
        returns.push_back(ret);
    }
    
    // 第二步：计算基础统计指标
    double avg_return = MathUtils::mean(returns);
    double volatility = MathUtils::standardDeviation(returns);
    double annualized_vol = MathUtils::annualizedVolatility(returns);
    
    // 第三步：计算技术指标
    auto sma_5 = MathUtils::simpleMovingAverage(stock_prices, 5);
    auto ema_10 = MathUtils::exponentialMovingAverage(stock_prices, 0.2);
    auto rsi_values = MathUtils::rsi(stock_prices, 14);
    
    // 第四步：风险指标
    double max_drawdown = MathUtils::maxDrawdown(stock_prices);
    
    // 第五步：验证结果
    EXPECT_GT(avg_return, -0.1);  // 平均收益率应该合理
    EXPECT_GT(volatility, 0.0);   // 波动率应该大于0
    EXPECT_GT(annualized_vol, 0.0);  // 年化波动率应该大于0
    EXPECT_EQ(sma_5.size(), stock_prices.size() - 4);  // SMA数组长度正确
    EXPECT_EQ(ema_10.size(), stock_prices.size());     // EMA数组长度正确
    EXPECT_GE(max_drawdown, 0.0);  // 最大回撤应该非负
    
    // 输出分析结果
    std::cout << "量化分析工作流程测试结果:" << std::endl;
    std::cout << "  平均收益率: " << (avg_return * 100) << "%" << std::endl;
    std::cout << "  日波动率: " << (volatility * 100) << "%" << std::endl;
    std::cout << "  年化波动率: " << (annualized_vol * 100) << "%" << std::endl;
    std::cout << "  最大回撤: " << (max_drawdown * 100) << "%" << std::endl;
    std::cout << "  最新SMA(5): " << (sma_5.empty() ? 0.0 : sma_5.back()) << std::endl;
    std::cout << "  最新EMA(10): " << (ema_10.empty() ? 0.0 : ema_10.back()) << std::endl;
    std::cout << "  最新RSI: " << (rsi_values.empty() ? 0.0 : rsi_values.back()) << std::endl;
    
    std::cout << "量化分析工作流程测试通过" << std::endl;
} 